package com.bp.hearthealth.pulse.lnapps.bp_ui.bp_activity.bp_blood_pressure

import androidx.room.Transaction
import com.bp.hearthealth.pulse.lnapps.bp_db.bp_bloodpressure.BloodPressure
import com.bp.hearthealth.pulse.lnapps.bp_db.bp_bloodpressure.BpBloodPressureDao
import com.bp.hearthealth.pulse.lnapps.bp_extension.LogUtil
import com.bp.hearthealth.pulse.lnapps.bp_network.BaseRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.withContext

class BpBloodPressureRepository(private val bloodPressureDao: BpBloodPressureDao) :
    BaseRepository() {

    @Transaction
    suspend fun insertBloodPressureWithPressureData(bloodPressure: BloodPressure) =
        withContext(Dispatchers.IO) {
            coroutineScope {
                try {
                    val reversedBloodPressureList = bloodPressure.bloodPressureList.reversed()
                    reversedBloodPressureList.forEach { bloodPressureData ->
                        bloodPressureDao.insertBloodPressureData(bloodPressureData)
                    }
                    bloodPressureDao.insertBloodPressure(bloodPressure.copy(bloodPressureList = reversedBloodPressureList))
//                    // 获取插入后的最新一条血压数据的 ID
//                    val newestBloodPressureDataId = bloodPressureDao.getNewestBloodPressureDataId()
//
//                    newestBloodPressureDataId
                } catch (e: Exception) {
                    0
                }
            }
        }


    private suspend fun insertBloodPressure(bloodPressure: BloodPressure) =
        withContext(Dispatchers.IO) {
            coroutineScope {
                try {
                    bloodPressureDao.insertBloodPressure(bloodPressure)
                } catch (e: Exception) {
                    LogUtil.e(e)
                    0
                }
            }
        }

    suspend fun getBloodPressureByUserId(userId: String) = withContext(Dispatchers.IO) {
        coroutineScope {
            try {
                bloodPressureDao.getBloodPressureByUserId(userId)
            } catch (e: Exception) {
                LogUtil.e(e)
                null
            }
        }
    }


    suspend fun getBloodPressureByDate(userId: String, date: Long) = withContext(Dispatchers.IO) {
        coroutineScope {
            try {
                bloodPressureDao.getBloodPressureByDate(userId, date)
            } catch (e: Exception) {
                LogUtil.e(e)
                null
            }
        }
    }


    suspend fun getBloodPressureDataBypid(pid: String) = withContext(Dispatchers.IO) {
        coroutineScope {
            try {
                bloodPressureDao.getBloodPressureDataById(pid)
            } catch (e: Exception) {
                LogUtil.e(e)
                null
            }
        }
    }

    suspend fun getBloodPressureDataByUserIdAndDate(userId: String, date: Long) =
        withContext(Dispatchers.IO) {
            coroutineScope {
                try {
                    bloodPressureDao.getBloodPressureByUserIdAndDate(
                        userId, date
                    )?.bloodPressureList
                } catch (e: Exception) {
                    LogUtil.e(e)
                    null
                }
            }
        }

    suspend fun updateUnlocked(id: String) = withContext(Dispatchers.IO) {
        coroutineScope {
            try {
                bloodPressureDao.updateBloodPressureDataUnlockedStatusById(
                    id = id, unlocked = true
                )
            } catch (e: Exception) {
                LogUtil.e(e)
                0
            }
        }
    }

    suspend fun deleteBloodPressureData(userId: String, date: Long, bpdId: String) =
        withContext(Dispatchers.IO) {
            coroutineScope {
                try {
                    val deletedRows = bloodPressureDao.deleteBloodPressureDataById(userId, bpdId)
                    //删除成功后，没有将数据从集合中移除掉
                    // 检查是否删除了最后一个 BloodPressureData
                    if (deletedRows > 0) {
                        // 获取用户的 BloodPressure 对象
                        val bloodPressure =
                            bloodPressureDao.getBloodPressureByIdAndDate(userId, date)
                        // 检查 BloodPressure 对象不为 null
                        if (bloodPressure != null) {
                            // 从 BloodPressure 对象的集合中移除已删除的 BloodPressureData
                            bloodPressure.bloodPressureList =
                                bloodPressure.bloodPressureList.filter { it.id != bpdId }
                            // 在数据库中更新 BloodPressure 对象
                            if (bloodPressure.bloodPressureList.isEmpty()) {
                                bloodPressureDao.deleteBloodPressure(bloodPressure)
                            } else {
                                bloodPressureDao.updateBloodPressure(bloodPressure)
                            }
                        }
                    }
                    deletedRows
                } catch (e: Exception) {
                    LogUtil.e(e)
                    0
                }
            }
        }

    //删除指定id下的BloodPressureData
    suspend fun deleteBloodPressureDataFromList(
        userId: String, bloodPressureId: Long, dataIdToDelete: String
    ) {
        coroutineScope {
            try {
                // 从数据库中获取指定 id 的 BloodPressure 对象
                val bloodPressure =
                    bloodPressureDao.getBloodPressureByUserIdAndDate(userId, bloodPressureId)

                // 获取该 BloodPressure 对象中的血压数据列表
                val bloodPressureList = bloodPressure!!.bloodPressureList.toMutableList()

                // 查找并删除指定 id 的 BloodPressureData 对象
                val iterator = bloodPressureList.iterator()
                while (iterator.hasNext()) {
                    val bloodPressureData = iterator.next()
                    if (bloodPressureData.id == dataIdToDelete) {
                        iterator.remove()
                        break
                    }
                }

                // 更新 BloodPressure 对象的血压数据列表
                val updatedBloodPressure = bloodPressure.copy(bloodPressureList = bloodPressureList)

                // 将更新后的 BloodPressure 对象保存到数据库中
                bloodPressureDao.updateBloodPressure(updatedBloodPressure)
            } catch (e: Exception) {
                LogUtil.e(e)
                0
            }
        }
    }

    suspend fun getBloodPressureDataForDateRange(
        userId: String, startOfDayInMillis: Long, endOfDayInMillis: Long
    ) = withContext(Dispatchers.IO) {
        // 获取今天的血压数据列表
        coroutineScope {
            try {
                bloodPressureDao.getBloodPressureDataForDate(
                    userId, startOfDayInMillis, endOfDayInMillis
                )
            } catch (e: Exception) {
                LogUtil.e(e)
                null
            }
        }
    }

    suspend fun getBloodPressureForDateRange(
        userId: String, startOfDayInMillis: Long, endOfDayInMillis: Long
    ) = withContext(Dispatchers.IO) {
        coroutineScope {
            try {
                bloodPressureDao.getBloodPressureForDateRange(
                    userId, startOfDayInMillis, endOfDayInMillis
                )
            } catch (e: Exception) {
                LogUtil.e(e)
                null
            }
        }
    }
}